home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Online / NNTPd / server / xover.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-01  |  10.3 KB  |  544 lines

  1. /* xover.c */
  2.  
  3. #include "common.h"
  4. #include "overview.h"
  5. #include "xover.h"
  6. #ifndef lint
  7. static char sccsid[] = "$Id: xover.c,v 1.2 1994/11/01 06:08:21 sob Exp sob $";
  8. #endif
  9. #if defined(XOVER) || defined(XROVER)
  10. void
  11. numlist(argc, argv, obj)
  12.     int        argc;
  13.     char        *argv[];
  14.     struct xobj    *obj;
  15. {
  16.     register int    low, high;
  17.     int        artnum, artptr;
  18.     FILE        *fp;
  19.  
  20.     if (!canread) {
  21.         printf("%d You only have permission to transfer, sorry.\r\n",
  22.             ERR_ACCESS);
  23.         (void) fflush(stdout);
  24.         return;
  25.     }
  26.  
  27.     if (!ingroup) {
  28.         printf("%d You are not currently in a newsgroup.\r\n",
  29.             ERR_NCING);
  30.         (void) fflush(stdout);
  31.         return;
  32.     }
  33.     if (argc != 1 && argc != 2) {
  34.         printf("%d Usage: %s [artrange]\r\n", ERR_CMDSYN, obj->cmd);
  35.         (void) fflush(stdout);
  36.         return;
  37.     }
  38.  
  39.     if (argc == 1) {
  40.         if (art_ptr < 0 || art_ptr >= num_arts) {
  41.             printf("%d No article is currently selected.\r\n",
  42.                 ERR_NOCRNT);
  43.             (void) fflush(stdout);
  44.             return;
  45.         }
  46.         high = low = art_array[art_ptr];
  47.         artptr = art_ptr;
  48.     } else {
  49.         register char *cp = index(argv[1], '-');
  50.         if (cp == NULL)
  51.             low = high = atoi(argv[1]);
  52.         else {
  53.             *cp++ = '\0';
  54.             low = atoi(argv[1]);
  55.             high = atoi(cp);
  56.             if (high < low)
  57.                 if (num_arts > 0)
  58.                     high = art_array[num_arts-1];
  59.                 else
  60.                     high = low;
  61.         }
  62.         artptr = 0;
  63.     }
  64.  
  65.     xfind(obj, low);
  66.     fp = obj->fp;
  67.  
  68.     /* Return the desired data.  This is written carefully to avoid
  69.      * over-long lines. */
  70.     printf("%d %s data follows\r\n", OK_OVER, obj->name);
  71.  
  72.     for (;artptr < num_arts; artptr++) {
  73.         if ((artnum = art_array[artptr]) < low)
  74.             continue;
  75.         if (artnum > high)
  76.             break;
  77.  
  78.         if (obj->num > 0 && obj->num < artnum)
  79.             xfind(obj, artnum);
  80.         if (obj->num == artnum) {
  81.             register int c;
  82.             printf("%d", artnum);
  83.             while ((c = getc(fp)) != EOF && c != '\n')
  84.                 putchar(c);
  85.             if (fscanf(fp, "%d", &obj->num) != 1)
  86.                 obj->num = -1;
  87.             printf("\r\n");
  88.         } else {
  89.             printf("%d", artnum);
  90.             (obj->fake)(artnum);
  91.         }
  92.     }
  93.     printf(".\r\n");
  94.     (void) fflush(stdout);
  95. }
  96. #endif
  97.  
  98. #ifdef XOVER
  99. FILE *over_open();
  100. void over_fake();
  101. struct xobj over = {0,-1,0,over_open,over_fake,"overview","XOVER"};
  102.  
  103. void
  104. doxover(argc, argv)
  105.     int        argc;
  106.     char        *argv[];
  107. {
  108.     numlist(argc, argv, &over);
  109. }
  110.  
  111. int
  112. over_is_cheap(low, high)
  113. int low, high;
  114. {
  115.     if (over.fp)
  116.         return 1;
  117.     if (over.open_tried)
  118.         return 0;
  119.     return high >= low;
  120. }
  121.  
  122. FILE *
  123. over_open()
  124. {
  125.     FILE *fp;
  126. #ifdef OVERVIEW_DIR
  127.     char name_buff[MAXPATHLEN], *cp;
  128.     sprintf(name_buff, "%s/", OVERVIEW_DIR);
  129.     cp = name_buff + strlen(name_buff);
  130.     strcpy(cp, group_name);
  131.     while ((cp = index(cp, '.')) != (char *) NULL)
  132.         *cp = '/';
  133.     sprintf(name_buff+strlen(name_buff), "/%s", OVER_NAME);
  134.     fp = fopen(name_buff, "r");
  135. #else
  136.     fp = fopen(OVER_NAME, "r");
  137. #endif
  138.     return fp;
  139. }
  140.  
  141. #define TOLOWER(c) (isupper(c) ? tolower(c) : (c))
  142.  
  143. int
  144. over_header(s)
  145. char *s;
  146. {
  147.     int i;
  148.     char ch;
  149.     ch = (isascii(*s)? TOLOWER(*s) : *s);
  150.  
  151.     for (i = 1; i < OVER_FIELD_COUNT; i++) {
  152.         if (ch == *over_field[i]) {
  153.             if (strcasecmp(s, over_field[i]) == 0)
  154.                 return i;
  155. #ifdef OVER_UNIQUE_1ST_LTRS
  156.             /* optimization assumes no 2 keywords w/same 1st ltr */
  157.             break;
  158. #endif
  159.         }
  160.     }
  161.     return -1;
  162. }
  163.  
  164. char *
  165. over_grab_header(hdr, output)
  166. int hdr;
  167. int output;
  168. {
  169.     int c;
  170.     int i = hdr;
  171.     char *buf = NULL;
  172.  
  173. #ifdef OVER_GROUP_FIELD
  174.     if (i > OVER_GROUP_FIELD)
  175.         i = OVER_GROUP_FIELD;
  176. #endif
  177.     while (i--) {
  178.         register int c;
  179.         while ((c = getc(over.fp)) != '\t')
  180.             if (c == EOF || c == '\n')
  181.                 goto no_contents;
  182.     }
  183.     c = getc(over.fp);
  184. #ifdef OVER_GROUP_FIELD
  185.     if (hdr >= OVER_GROUP_FIELD) {
  186.         for (i = 0; c != EOF && c != '\n'; i++) {
  187.             if (c == ':' && !over_field[hdr][i]) {
  188.                 do {
  189.                     c = getc(over.fp);
  190.                 } while (c == ' ');
  191.                 break;
  192.             }
  193.             if (TOLOWER(c) != over_field[hdr][i]) {
  194.                 while (c != '\t') {
  195.                     if (c == EOF || c == '\n')
  196.                         goto no_contents;
  197.                     c = getc(over.fp);
  198.                 }
  199.                 i = -1;
  200.             }
  201.             c = getc(over.fp);
  202.         }
  203.     }
  204. #endif
  205.     if (c == EOF || c == '\n' || c == '\t') {
  206. no_contents:
  207.         if (output)
  208.             printf("(none)\r\n");
  209.     } else if (output) {
  210.         do {
  211.             putchar(c);
  212.             c = getc(over.fp);
  213.         } while (c != EOF && c != '\n' && c != '\t');
  214.         printf("\r\n");
  215.     } else {
  216.         char        *malloc(), *realloc();
  217.         register int    size = 1024;
  218.         buf = malloc(size);
  219.         if (buf) {
  220.             register int    pos = 0;
  221.             do {
  222.                 if (pos >= size-1) {
  223.                     size += 1024;
  224.                     buf = realloc(buf, size);
  225.                     if (!buf)
  226.                         break;
  227.                 }
  228.                 buf[pos++] = c;
  229.                 c = getc(over.fp);
  230.             } while (c != EOF && c != '\n' && c != '\t');
  231.             if (buf)
  232.                 buf[pos] = '\0';
  233.         }
  234.     }
  235.     while (c != EOF && c != '\n')
  236.         c = getc(over.fp);
  237.     if (c == EOF || fscanf(over.fp, "%d", &over.num) != 1)
  238.         over.num = -1;
  239.     return buf;
  240. }
  241.  
  242. void
  243. over_fake(artnum)
  244. int artnum;
  245. {
  246.     char        line[NNTP_STRLEN];
  247.     register FILE    *fp;
  248.     register char    *cp, *cp2;
  249.     register int    hdr;
  250.     char        *array[OVER_FIELD_COUNT];
  251.     char        *malloc(), *realloc();
  252.  
  253.     (void) sprintf(line, "%d", artnum);
  254.     fp = fopen(line, "r");
  255.     if (fp == NULL)
  256.         return;
  257.  
  258.     for (hdr = OVER_FIELD_COUNT-1; hdr > 0; hdr--) {
  259.         array[hdr] = 0;
  260.     }
  261.     cp = line;
  262.     while (fgets(line, sizeof line, fp) != NULL) {
  263.         if (cp && *line == '\n') {
  264.             break;
  265.         }
  266.         cp2 = cp;
  267.         cp = index(line, '\n');
  268.         if (!cp2 || isspace(*line)) {
  269.             if (hdr > 0 && array[hdr]) {
  270.                 register int len = strlen(array[hdr]);
  271.                 if (cp2) {
  272.                     for (cp2 = line+1; isspace(*cp2); cp2++)
  273.                         ;
  274.                     *--cp2 = ' ';
  275.                 }
  276.                 else
  277.                     cp2 = line;
  278.                 if (cp)
  279.                     *cp = '\0';
  280.                 array[hdr] = realloc(array[hdr],
  281.                              strlen(cp2) + len + 1);
  282.                 if (array[hdr])
  283.                     strcpy(array[hdr] + len, cp2);
  284.             }
  285.         } else if ((cp2 = index(line, ':')) != NULL) {
  286.             *cp2 = '\0';
  287.             if ((hdr = over_header(line)) > 0) {
  288.                 if (array[hdr])
  289.                     continue;  /* a duplicate header?!? */
  290.                 cp2 += 2;
  291.                 if (cp)
  292.                     *cp = '\0';
  293.                 array[hdr] = malloc(strlen(cp2) + 1);
  294.                 if (array[hdr])
  295.                     strcpy(array[hdr], cp2);
  296.             }
  297.         } else
  298.             hdr = 0;
  299.     }
  300.  
  301.     for (hdr = 1; hdr < OVER_FIELD_COUNT; hdr++) {
  302.         putchar('\t');
  303.         if (array[hdr]) {
  304. #if defined(OVER_XREFS) && defined(OVER_XREF_PREFIX)
  305.             if (hdr == 8)
  306.                 printf("xref: ");
  307. #endif
  308.             printf("%s", array[hdr]);
  309.             free(array[hdr]);
  310.         } else if (hdr == 6) {        /* Fudge the byte header */
  311.             struct stat s;
  312.             fstat(fileno(fp), &s);
  313.             printf("%u", s.st_size);
  314.         }
  315.     }
  316.     printf("\r\n");
  317.  
  318.     (void) fclose(fp);
  319. }
  320. #endif
  321.  
  322. #ifdef XROVER
  323. FILE *rover_open();
  324. void rover_fake();
  325. struct xobj rover = {0,-1,0,rover_open,rover_fake,"reference","XROVER"};
  326.  
  327. void
  328. doxrover(argc, argv)
  329.     int        argc;
  330.     char        *argv[];
  331. {
  332.     numlist(argc, argv, &rover);
  333. }
  334.  
  335. FILE *
  336. rover_open()
  337. {
  338.     FILE *fp;
  339. #ifdef ROVER_DIR
  340.     char name_buff[MAXPATHLEN], *cp;
  341.     sprintf(name_buff, "%s/", ROVER_DIR);
  342.     cp = name_buff + strlen(name_buff);
  343.     strcpy(cp, group_name);
  344.     while ((cp = index(cp, '.')) != (char *) NULL)
  345.         *cp = '/';
  346.     sprintf(name_buff+strlen(name_buff), "/%s", ROVER_NAME);
  347.     fp = fopen(name_buff, "r");
  348. #else
  349.     fp = fopen(ROVER_NAME, "r");
  350. #endif
  351.     return fp;
  352. }
  353.  
  354. void
  355. rover_fake(artnum)
  356.     int artnum;
  357. {
  358.     char        line[NNTP_STRLEN];
  359.     register FILE    *fp;
  360.     register char    *cp, *cp2;
  361.     char        *references = NULL;
  362.     char        *malloc(), *realloc();
  363.  
  364. #ifdef XOVER
  365.     if (over_is_cheap(artnum, artnum)) {
  366.         int hdr = over_header("references");
  367.         if (hdr >= 0 && xfind(&over, artnum)) {
  368.             references = over_grab_header(hdr, 0);
  369.             goto output_refs;
  370.         }
  371.     }
  372. #endif
  373.     (void) sprintf(line, "%d", artnum);
  374.     fp = fopen(line, "r");
  375.     if (fp == NULL)
  376.         return;
  377.  
  378.     cp = line;
  379.     while (fgets(line, sizeof line, fp) != NULL) {
  380.         if (cp && *line == '\n') {
  381.             break;
  382.         }
  383.         cp2 = cp;
  384.         cp = index(line, '\n');
  385.         if (!cp2 || isspace(*line)) {
  386.             if (references) {
  387.                 register int len = strlen(references);
  388.                 if (cp2) {
  389.                     for (cp2 = line+1; isspace(*cp2); cp2++)
  390.                         ;
  391.                     *--cp2 = ' ';
  392.                 }
  393.                 else
  394.                     cp2 = line;
  395.                 if (cp)
  396.                     *cp = '\0';
  397.                 references = realloc(references,
  398.                              strlen(cp2) + len + 1);
  399.                 if (references)
  400.                     strcpy(references + len, cp2);
  401.             }
  402.         } else if (references)
  403.             break;
  404.         else if ((cp2 = index(line, ':')) != NULL) {
  405.             *cp2 = '\0';
  406.             if (strcasecmp(line, "references") == 0) {
  407.                 cp2 += 2;
  408.                 if (cp)
  409.                     *cp = '\0';
  410.                 references = malloc(strlen(cp2) + 1);
  411.                 if (references)
  412.                     strcpy(references, cp2);
  413.             }
  414.         }
  415.     }
  416.  
  417.     (void) fclose(fp);
  418.  
  419. #ifdef XOVER
  420. output_refs:
  421. #endif
  422.     if (references) {
  423.         cp2 = references + strlen(references) - 1;
  424.         while ((cp = rindex(references, '<')) != NULL) {
  425.             while (cp2 >= cp
  426.                 && ((unsigned char)*cp2 <= ' ' || *cp2 == ','))
  427.                 cp2--;
  428.             cp2[1] = '\0';
  429.             /* Quit parsing references if this one is garbage. */
  430.             if (!valid_message_id(cp, cp2))
  431.                 break;
  432.             /* Dump all domains that end in '.' */
  433.             if (cp2[-1] == '.')
  434.                 break;
  435.             if (!gethistent(cp, 0) || group_artnum == 0)
  436.                 printf(" %s", cp);
  437.             else {
  438.                 printf(" %d", group_artnum);
  439.                 break;
  440.             }
  441.             *cp = '\0';
  442.             cp2 = cp-1;
  443.         }
  444.         free(references);
  445.     }
  446.     printf("\r\n");
  447. }
  448.  
  449. /* Check if the string we've found looks like a valid message-id reference.
  450. */
  451. int
  452. valid_message_id(start, end)
  453. register char *start, *end;
  454. {
  455.     char *mid;
  456.  
  457.     if (start == end)
  458.         return 0;
  459.  
  460.     if (*end != '>') {
  461.         /* Compensate for space cadets who include the header in their
  462.         ** subsitution of all '>'s into another citation character. */
  463.         if (*end == '<' || *end == '-' || *end == '!' || *end == '%'
  464.          || *end == ')' || *end == '|' || *end == ':' || *end == '}'
  465.          || *end == '*' || *end == '+' || *end == '#' || *end == ']'
  466.          || *end == '@' || *end == '$')
  467.             *end = '>';
  468.     } else if (end[-1] == '>') {
  469.         *(end--) = '\0';
  470.     }
  471.     /* Id must be "<...@...>" */
  472.     if (*start != '<' || *end != '>' || (mid = index(start, '@')) == NULL
  473.      || mid == start+1 || mid+1 == end)
  474.         return 0;
  475.     return 1;
  476. }
  477. #endif
  478.  
  479. #if defined(XOVER) || defined(XROVER)
  480. int
  481. xfind(obj, artnum)
  482.     struct xobj    *obj;
  483.     int        artnum;
  484. {
  485.     FILE        *fp = obj->fp;
  486.     int        file_num = obj->num;
  487.     if (fp) {
  488.         if (file_num < 0 || file_num > artnum) {
  489.             fseek(fp, 0L, 0);
  490.             file_num = 0;
  491.         }
  492.     } else {
  493.         if (!obj->open_tried)
  494.             obj->fp = fp = (obj->open)();
  495.         obj->open_tried = 1;
  496.         if (!fp) {
  497.             obj->num = -1;
  498.             return 0;
  499.         }
  500.         file_num = 0;
  501.     }
  502.     if (!file_num)
  503.         fscanf(fp, "%d", &file_num);
  504.     while (1) {
  505.         register int c;
  506.         if (feof(fp)) {
  507.             file_num = -1;
  508.             break;
  509.         }
  510.         if (file_num >= artnum) {
  511.             break;
  512.         }
  513.         while ((c = getc(fp)) != EOF && c != '\n')
  514.             continue;
  515.         fscanf(fp, "%d", &file_num);
  516.     }
  517.     obj->num = file_num;
  518.     return file_num == artnum;
  519. }
  520.  
  521. void
  522. xclose(obj)
  523. struct xobj *obj;
  524. {
  525.     if (obj->fp) {
  526.         fclose(obj->fp);
  527.         obj->fp = NULL;
  528.         obj->num = -1;
  529.     }
  530.     obj->open_tried = 0;
  531. }
  532.  
  533. void
  534. close_xfiles()
  535. {
  536. #ifdef XOVER
  537.     xclose(&over);
  538. #endif
  539. #ifdef XROVER
  540.     xclose(&rover);
  541. #endif
  542. }
  543. #endif
  544.